package com.gcosc.hly.codejava.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gcosc.hly.codejava.Utils.RequestContextUtils;
import com.gcosc.hly.codejava.Utils.StringUtils;
import com.gcosc.hly.codejava.VO.AnswerDetailVO;
import com.gcosc.hly.codejava.VO.AnswerItemDetailVO;
import com.gcosc.hly.codejava.VO.AnswerVO;
import com.gcosc.hly.codejava.VO.PageResult;
import com.gcosc.hly.codejava.entity.Answer;
import com.gcosc.hly.codejava.entity.Paper;
import com.gcosc.hly.codejava.mapper.AnswerMapper;
import com.gcosc.hly.codejava.mapper.PaperMapper;
import com.gcosc.hly.codejava.params.QueryParams;
import com.gcosc.hly.codejava.result.Code;
import com.gcosc.hly.codejava.service.AnswerItemService;
import com.gcosc.hly.codejava.service.AnswerService;
import com.gcosc.hly.codejava.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, Answer> implements AnswerService {

    private final AnswerItemService answerItemService;
    private final PaperMapper paperMapper;
    private final UserService userService;

    @Override
    public PageResult<AnswerVO> queryParams(QueryParams params) {
        int id = RequestContextUtils.getUser().getId();
        int isUser = params == null ? 0 : params.getIsUser();

        List<Integer> paperIds = null;

        if (StringUtils.isNotEmpty(params.getPaperTitle())){
            LambdaQueryWrapper<Paper> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(Paper::getId)
                    .like(Paper::getTitle, params.getPaperTitle());
            paperIds = paperMapper.selectList(wrapper).stream().map(n -> n.getId()).collect(Collectors.toList());
        }

        Page<Answer> page = lambdaQuery()
                .orderByDesc(params.getDesc() == null, Answer::getCreateTime)
                .orderByDesc("fraction".equals(params.getDesc()), Answer::getFraction)
                .eq(isUser == 0, Answer::getUid, id)//是否只查询自己的
                .eq(params.getAnswerId() != 0, Answer::getId, params.getAnswerId())//根据答题卡id查询
                .eq(params.getPaperId() != 0, Answer::getPaperId, params.getPaperId())//根据试卷id查询
                .in(paperIds != null, Answer::getPaperId, paperIds)//根据试卷id查询
                .eq(params.getUid() != 0, Answer::getUid, params.getUid())//根据用户id查询
                .eq(params.getStatus() != 0, Answer::getStatus, params.getStatus() == -1 ? 0 : params.getStatus())//
                .page(new Page<Answer>(params.getPage(), params.getLimit()));

        List<AnswerVO> collect = page.getRecords().stream().map(n -> {
            Paper paper = paperMapper.selectById(n.getPaperId());

            if (paper.getShowScore() == 0 && isUser == 0){
                n.setFraction(0);
            }

            return AnswerVO.builder()
                    .answer(n)
                    .paper(paper)
                    .user(userService.getUserInfoVO(n.getUid()))
                    .build();
        }).collect(Collectors.toList());

        page.setRecords(null);

        return PageResult.<AnswerVO>builder().page(page).list(collect).build();
    }

    @Override
    public int edit(Answer answer) {
        if (answer.getId() == 0){
            answer.setUid(RequestContextUtils.getUser().getId());
            save(answer);
        }else {
            Answer byId = getById(answer.getId());
            byId.setFraction(answer.getFraction());
            byId.setStatus(answer.getStatus());
            byId.setSubmitTime(answer.getSubmitTime());
            if (byId.getStatus() != 0){

                if (byId.getSubmitTime() == null)
                    byId.setSubmitTime(new Date());

                if (byId.getStatus() == 1 && lambdaQuery()
                        .eq(Answer::getId, byId.getId())
                        .eq(Answer::getStatus, 2).one() != null){
                    Code.BUSINESS_ERR("答题已超时！");
                }

                byId.setFraction(answerItemService.countFraction(byId.getId()));
            }
            updateById(byId);
        }
        return answer.getId();
    }

    @Override
    public AnswerDetailVO getDetail(int id) {

        Answer answer = getById(id);

        List<AnswerItemDetailVO> detailList = answerItemService.getDetailList(id);

        Paper paper = paperMapper.selectById(answer.getPaperId());

        ArrayList<Integer> ids = new ArrayList<>();

        Arrays.stream(paper.getList().split(",")).forEach(n -> {
            Integer integer = Integer.valueOf(n);
            for (AnswerItemDetailVO answerItemDetailVO : detailList) {
                if (answerItemDetailVO.getTopic().getId() == integer){
                    return;
                }
            }
            ids.add(integer);
        });

        List<AnswerItemDetailVO> list = Stream.of(detailList, answerItemService.getDetailByTopicIdsList(ids))
                .flatMap(Collection::stream).collect(Collectors.toList());

        list.forEach(n -> {
            if (n.getAnswerItem() != null){
                n.setUser(userService.getUserInfoVO(n.getAnswerItem().getUid()));
            }
        });

        userService.clear();

        return AnswerDetailVO.builder()
                .paper(paper)
                .list(list)
                .answer(answer)
                .build();
    }

}
